﻿//*************************************************************************
//面向服务的协作式智能交通系统仿真软件SoC-ITSS v2.1 alpha
//发布单位：西北工业大学--巴黎高科MINES机器人与群智能系统联合实验室
//团队负责人：张凯龙 Zhang Kailong
//团队成员：张大方、杨安胜、王敏、谢策、王雨佳、谢尘玉等
//联系我们：kl.zhang@nwpu.edu.cn
//2012-2021
//*************************************************************************

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CyberCarSimulation.Regulation;
using CyberCarSimulation.Algorithm;
using CyberCarSimulation.Bean;
using CyberCarSimulation.RoadModel;
using CyberCarSimulation.Cloud;
//*******************************************************
//
//文件名(File Name):           Main.cs
//
//数据表(Tables):              nothing 

//          修改理由：         主程序
//
//*******************************************************

namespace CyberCarSimulation.Simulation
{
    class Main
    {

        //时间参数
        //public static int PathPlaneTime = 0;
        public static readonly float TimeStep = 0.04f;      //时间片段的取值
        private static int TimeStepIndex = 0;   //时间片段计数值
        private static float GlobalTime;        //全局时间，即TimeStep*TimeIndex


        public static int Passed_ID;    //已通过的车辆的数目
        public int High_Vehicle_Num = (int)(MainData.SimulationConfig.GetTxtVehicleQuantity() * MainData.SimulationConfig.GetTxtHighPriorPercentage() + 0.1);    //高优先级车辆的数量，在仿真之前计算出数量
        public int Mid_Vehicle_Num = (int)(MainData.SimulationConfig.GetTxtVehicleQuantity() * MainData.SimulationConfig.GetTxtMidPriorPercentage() + 0.1);      //中优先级车辆的数量，在仿真之前计算出数量

      
        private Simulation Simu = null;                    //创建Simulation对象  生成交通流，以及车辆个体的具体信息
        private HandleAlgorithm HandleAlgorithm = null;    //创建调度算法HandleAlgorithm对象 管理算法的调度     

        public static List<Vehicle> RemoveVehicleListFromGlobal = new List<Vehicle>();
        
        //构造函数
        public Main()
        {
            //初始化几个类的参数
            Definitions.init();
            Directions.setParams();
            SCS_ID.setParams();
            Coordinate.setParams();
            Vehicle.setParms();

            //初始化交通云
            MainData.TrafficCloud = new TrafficCloudBPR(MainData.Map.GetID(), MainData.CenterLaneList.Count);
            MainData.TrafficCloud.init();
            MainData.TrafficCloud.ExecuteGlobalAlgorithm();

            //从MainData中拿到配置参数，车流密度、车辆数目、大车数量
            float VehicleDensity = MainData.SimulationConfig.GetTxtVehicleDensity();
            int VehicleQuantity = MainData.SimulationConfig.GetTxtVehicleQuantity();
            float PercentageBig = MainData.SimulationConfig.GetTxtPercentageBig();

            //创建Simu、HandleAlgorithm等对象
            Simu = new Simulation(VehicleDensity, this.High_Vehicle_Num, this.Mid_Vehicle_Num, VehicleQuantity, PercentageBig);
            HandleAlgorithm = new HandleAlgorithm();               
            Simu.initVehicleQueue();            
        }

        /************************************************************************/
        /* 返回未插入车辆队列是否为空                              */
        /************************************************************************/
        public bool isVehicleQueueEmpty()
        {
            return Simu.isVehicleQueueEmpty();
        }

        //获取当前总时间
        public static float GetGlobalTime()
        {
            return (float)Math.Round(Main.GlobalTime, Definitions.Precise);
        }

         /************************************************************************/
        /* 对外的仿真接口，通过调用vehicle.cs与sche完成所有的仿真功能               */
        /************************************************************************/
        public void Simulation()
        {            

            //更新车辆信息
            //this.updateVehicleInformation();
            this.updateVehicleInformation1();

            //清理消息队列AtoV
            lock (MainData.__ITSLockWasTaken)             //添加lock关键字
            {
                foreach (Intersection Intersection in MainData.CEIntersectionList)
                {
                    List<Message> AtoV_BufferTemp = Intersection.GetAtoV_Buffer();
                    AtoV_BufferTemp.Clear();
                    Intersection.SetAtoV_Buffer(AtoV_BufferTemp);
                }
            }

            //执行算法操作
            this.scheduleVehicle();

            //清理消息队列VtoA
            lock (MainData.__ITSLockWasTaken)             //添加lock关键字
            {
                foreach (Intersection Intersection in MainData.CEIntersectionList)
                {
                    List<Message> VtoA_BufferTemp = Intersection.GetVtoA_Buffer();
                    VtoA_BufferTemp.Clear();
                    Intersection.SetVtoA_Buffer(VtoA_BufferTemp);
                }
            }
            this.updateGlobalTime();
            this.RecoverDisUpdate();
        }


        /************************************************************************/
        /* 更新现有车辆的所有相关信息：xc  Test
         * 1、调用车辆的仿真函数，完成演示区内车辆的更新动作。
         * 2、加入更新的车辆
         * 3、对于将离开临界区的车辆，进行操作
         */
        /************************************************************************/
        private void updateVehicleInformation1()
        {
            MainData.TrafficCloud.ExecuteGlobalAlgorithm(); //更新权重


            Main.RemoveVehicleListFromGlobal.Clear();

            /*更新车辆的相关信息  遍历全局List中每一辆车辆 对车辆进行控制*/
            for (int i = 0; i < MainData.Map.GlobalVehicleList.Count; i++) 
            {
                
                Vehicle vtmp = MainData.Map.GlobalVehicleList[i];             
                vtmp.vehicleControl();
            }

            //删除离开的车辆
            for (int i = 0; i < Main.RemoveVehicleListFromGlobal.Count; i++) 
            {
                Vehicle VehicleTemp = Main.RemoveVehicleListFromGlobal[i];
                MainData.Map.GlobalVehicleList.Remove(VehicleTemp);
            }


            /*插入新的车辆，并设置该车辆的前车*/
            Vehicle v = null;

            for (int i = 0; i < MainData.EnterLaneList.Count; i++)  //注意List读取与修改不能并行操作
            {
                Lane L = MainData.EnterLaneList[i];               
                v = Simu.insertVehicle(L);   //插入车辆
                if (v != null)
                {
                    //更新前车
                    v.updateFrontVehicle(0);

                    ////设置车辆的所属路口
                    //Lane lane = Lane.FindLaneByID(v.Get_Current_LaneID());      //获取当前车辆所在车道
                    //Intersection intersection = Intersection.FindIntersectionByID(lane.GetEnterCEIntID());
                    //string intersectionid = intersection.GetID();                   

                    //v.SetIntersectionID(intersectionid);
                    //int intersectionnum = int.Parse(intersectionid.Substring(3, 2));
                    //v.SetIntersectionNumber(intersectionnum);


                    // //设置车辆最终路口
                    //Lane finallane = Lane.FindLaneByID(v.Get_Final_LaneID());
                    //Intersection finalintersection = Intersection.FindIntersectionByID(lane.GetEnterCEIntID());
                    //string intersectionfianlid = finalintersection.GetID();

                    //v.SetIntersectionFinalID(intersectionfianlid);
                    //int intersectionfinalnum = int.Parse(intersectionfianlid.Substring(3, 2));
                    //v.SetIntersectionFinalNumber(intersectionfinalnum);
                    
                    
                    //将车辆从车道的queue中加入到车道的List中
                    List<Vehicle> VehicleList = L.GetVehicleList();
                    VehicleList.Add(v);
                    L.SetVehicleList(VehicleList);

                    //将车辆加入到全局的List中
                    MainData.Map.GlobalVehicleList.Add(v);

                    v.Set_TimeInsert(Main.getGlobalTime());
                    MainData.UpdateLaneList(L);
                }
             
            }

            //Main.PathPlaneTime++;
            //if (Main.PathPlaneTime >= 50) 
            //{
            //    Main.PathPlaneTime = 0;
            //}

            /*行走距离超出规定的车辆视为离开监控区域，自动移除到对应的xxxxDeleteQueue中*/
            //xc????????????

                    
        }

        private void updateVehicleInformation()
        {
            /*更新车辆的相关信息  遍历全局List中每一辆车辆 对车辆进行控制*/
            foreach (Vehicle vtmp in MainData.Map.GlobalVehicleList)
            {
                vtmp.vehicleControl();
            }

            /*插入新的车辆，并设置该车辆的前车*/
            Vehicle v = null;

            foreach (Lane L in MainData.EnterLaneList)
            {
                v = Simu.insertVehicle(L);   //插入车辆
                if (v != null)
                {
                    v.updateFrontVehicle(0);

                    //将车辆从车道的queue中加入到车道的List中
                    List<Vehicle> VehicleList = L.GetVehicleList();
                    VehicleList.Add(v);
                    L.SetVehicleList(VehicleList);

                    //将车辆加入到全局的List中
                    MainData.Map.GlobalVehicleList.Add(v);

                    v.Set_TimeInsert(Main.getGlobalTime());
                }
            }


            

            /*行走距离超出规定的车辆视为离开监控区域，自动移除到对应的xxxxDeleteQueue中*/
            //xc????????????


        }

        //获取当前总时间
        public static float getGlobalTime()
        {
            return (float)Math.Round(Main.GlobalTime, Definitions.Precise);
        }
        

        /************************************************************************/
        /* 更新全局时间                                                                     */
        /************************************************************************/
        private void updateGlobalTime()
        {
            Main.GlobalTime += Main.TimeStep;
            Main.TimeStepIndex++;
        }

        /************************************************************************/
        /* 将所有车辆的IsDisUpadated复位，使其标志为                                                                     */
        /************************************************************************/
        public void RecoverDisUpdate()
        {
            foreach (Vehicle vtmp in MainData.Map.GlobalVehicleList)
            {
                vtmp.State_IsDisUpadated = false;
            }
        }

         /************************************************************************/
        /* 车辆调度函数                                                                     */
        /************************************************************************/
        private void scheduleVehicle()
        {
            HandleAlgorithm.ExecuteAlgorithmMIX();//混合调度算法
            //执行算法,完成多路口的调度


            //if (MainData.FormConfig.GetFAFPSV()) 
            //{
            //    HandleAlgorithm.ExecuteAlgorithmFAFPSV();
            //}

            //if (MainData.FormConfig.GetFAFPMQ())
            //{
            //    HandleAlgorithm.ExecuteAlgorithmFIFOMQ();
            //}

            //if (MainData.FormConfig.GetHWFPSQ())
            //{
            //    HandleAlgorithm.ExecuteAlgorithmHWFPSQ();
            //}

            //if (MainData.FormConfig.GetHWFPSQSV())
            //{
            //    HandleAlgorithm.ExecuteAlgorithmHWFPSQSV();
            //}
            //else 
            //{
            //    HandleAlgorithm.ExecuteAlgorithmMIX();//混合调度算法
            //}



            
            //HandleAlgorithm.ExecuteAlgorithm();

            //HandleAlgorithm.ExecuteAlgorithmFIFOMQ();

            //HandleAlgorithm.ExecuteAlgorithmHWFPSQ();

            //HandleAlgorithm.ExecuteAlgorithmHWFPSQSV();
            
        }



    }
}
